﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Portfolio.BL.Common;
using Portfolio.Entities;
using Portfolio.Repository.ArticleCategories;
using Portfolio.BL.Dictionary;
using Portfolio.Repository.Articles;

namespace Portfolio.BL.ArticleCategories
{
    /// <summary>
    /// Klasa biznesowa operacje (dod,mod,us) na kategoriach artykułów.
    /// </summary>
    public class ArticleCategoryOperBL : InformationUser 
    {
        private ArticleCategoryT _articleCategory;        
        
        public ArticleCategoryOperBL(int pArticleCategoryID) : base()
        {
            _articleCategory = new ArticleCategoryT();
            if (pArticleCategoryID != 0)
            {
                using (ArticleCategoriesRepository articleCategoriesRepository = new ArticleCategoriesRepository())
                {
                    _articleCategory = articleCategoriesRepository.GetArticleCategoryByIdCategory(pArticleCategoryID);
                }
            }
            else
            {
                _articleCategory = null;
            }
        }

        public ArticleCategoryT ArticleCategory
        {
            get
            {
                return _articleCategory;
            }
        }

        /// <summary>
        /// Dodaje nową kategorię
        /// </summary>
        /// <param name="ArticleCategory">Nowa kategoria</param>
        /// <returns></returns>
        public int InsertArticleCategory(ArticleCategoryT pArticleCategory)
        {
            int countAllArticleCategories = 0;
            int articleCategoryID = 0;
            ArticleCategoryT articleCategoryTemp;            
            try
            {
                using (ArticleCategoriesRepository articleCategoriesRepository = new ArticleCategoriesRepository())
                {
                    countAllArticleCategories = articleCategoriesRepository.GetCountSeqAllArticleCategory() + 1;
                    //uzupełnienie o pozostałe elementy kategorii
                    pArticleCategory.SeqCategory = articleCategoriesRepository.GetMaxSeqArticleCategoriesByIDIDCategory(pArticleCategory.ArticleCategoryIDID) + 1;
                    //czy jest nadrzędna kategoria
                    if (pArticleCategory.ArticleCategoryIDID == null)
                    {
                        pArticleCategory.DepthLevel = 0;
                        pArticleCategory.SeqAllCategory = countAllArticleCategories;
                    }
                    else
                    {
                        pArticleCategory.DepthLevel = 1;
                        pArticleCategory.SeqAllCategory = articleCategoriesRepository.GetMaxSeqAllArticleCategoriesByIDIDCategory(pArticleCategory.ArticleCategoryIDID) + 1;
                    }
                    //modyfikacja pozostałych kategorii SeqAll
                    using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                    {                        
                        while (pArticleCategory.SeqAllCategory < countAllArticleCategories)
                        {
                            countAllArticleCategories -= 1;
                            articleCategoryTemp = articleCategoriesRepository.GetArticleCategoryBySeqAll(countAllArticleCategories);
                            articleCategoryTemp.SeqAllCategory = countAllArticleCategories + 1;
                            articleCategoryOperRepository.UpdateArticleCategory(articleCategoryTemp);
                        }
                    }
                    //dodawanie kategorii
                    using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                    {
                        int idArticleCategory = articleCategoryOperRepository.InsertArticleCategory(pArticleCategory);
                    }
                }

                InformationSuccess = InformationUserDictionary.Instance.GetInformationSuccessText(3);                
                return articleCategoryID;
            }
            catch (Exception ex)
            {
                InformationException = InformationUserDictionary.Instance.GetInformationExceptionText(10) + ex.Message;
                return articleCategoryID;
            }
        }

        /// <summary>
        /// Metoda użytkownika
        /// Modyfikuje wybraną kategorię
        /// </summary>
        /// <param name="ArticleCategory">Wybrana kategoria</param>
        public int UpdateArticleCategory(ArticleCategoryT pArticleCategory)
        {
            List<ArticleCategoryT> listArticleCategoriesTemp;
            ArticleCategoryT articleCategoryTemp;
            int articleCategoryID = 0;            
            try
            {
                using (ArticleCategoriesRepository articleCategoriesRepository = new ArticleCategoriesRepository())
                {
                    //czy jest ta sama kategoria nadrzednej
                    if (pArticleCategory.ArticleCategoryIDID == _articleCategory.ArticleCategoryIDID)
                    {
                        //uzupelniam dane, nastepnie wykonuje update
                        pArticleCategory.SeqAllCategory = _articleCategory.SeqAllCategory;
                        pArticleCategory.SeqCategory = _articleCategory.SeqCategory;
                        pArticleCategory.DepthLevel = _articleCategory.DepthLevel;
                        using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                        {
                            articleCategoryID = articleCategoryOperRepository.UpdateArticleCategory(pArticleCategory);
                        }
                    }
                    else
                    {
                        int seqall = _articleCategory.SeqAllCategory;
                        if (pArticleCategory.ArticleCategoryIDID == null)
                        {
                            pArticleCategory.DepthLevel = 0;
                        }
                        else
                        {
                            pArticleCategory.DepthLevel = 1;
                        }
                        pArticleCategory.SeqCategory = articleCategoriesRepository.GetMaxSeqArticleCategoriesByIDIDCategory(pArticleCategory.ArticleCategoryIDID) + 1;
                        pArticleCategory.SeqAllCategory = articleCategoriesRepository.GetMaxSeqAllArticleCategoriesByIDIDCategory(pArticleCategory.ArticleCategoryIDID) + 1;
                        //sprawdza seq all czy zmienia się na wyższą czy na niższą, i modyfikuje seqall dla pozostałych kategorii
                        if (pArticleCategory.SeqAllCategory > _articleCategory.SeqAllCategory)
                        {
                            pArticleCategory.SeqAllCategory -= 1;                            
                            using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                            {
                                for (int i = _articleCategory.SeqAllCategory; i < pArticleCategory.SeqAllCategory; i++)                                 
                                {                                    
                                    articleCategoryTemp = articleCategoriesRepository.GetArticleCategoryBySeqAll(i+1);
                                    articleCategoryTemp.SeqAllCategory = i-1;
                                    articleCategoryOperRepository.UpdateArticleCategory(articleCategoryTemp);
                                }
                            }
                        }
                        else if (pArticleCategory.SeqAllCategory < _articleCategory.SeqAllCategory)
                        {   
                            using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                            {
                                for (int i = _articleCategory.SeqAllCategory; pArticleCategory.SeqAllCategory < i; i--)                                 
                                {   
                                    articleCategoryTemp = articleCategoriesRepository.GetArticleCategoryBySeqAll(i-1);
                                    articleCategoryTemp.SeqAllCategory = i + 1;
                                    articleCategoryID = articleCategoryOperRepository.UpdateArticleCategory(articleCategoryTemp);
                                }
                            }                            
                        }                      

                        //update właściwej kategorii
                        using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                        {
                            articleCategoryID = articleCategoryOperRepository.UpdateArticleCategory(pArticleCategory);
                        }

                        //modyfikacja seq dla jednej rodziny
                        listArticleCategoriesTemp = articleCategoriesRepository.GetArticleCategoriesByIDIDCategoryIsNull(_articleCategory.ArticleCategoryIDID);                        
                        using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                        {
                            int i = 1;
                            foreach (ArticleCategoryT item in listArticleCategoriesTemp)
                            {
                                item.SeqCategory = i;
                                articleCategoryOperRepository.UpdateArticleCategory(item);
                                i++;
                            }
                        }
                    }
                }
                InformationSuccess = InformationUserDictionary.Instance.GetInformationSuccessText(2);
                return articleCategoryID;                
            }
            catch (Exception ex)
            {                
                InformationException = InformationUserDictionary.Instance.GetInformationExceptionText(9) + ex.Message;
                return articleCategoryID;
            }
        }

        /// <summary>
        /// Metoda użytkownika
        /// Usuwa wybraną kategorię
        /// </summary>
        /// <param name="ArticleCategory">Zaznaczona kategoria</param>
        public void DeleteArticleCategory()
        {            
            List<ArticleCategoryT> listArticleCategoriesTemp;
            List<ArticleT> listArticles;
            ArticleCategoryT articleCategoryTemp;
            try
            {
                using (ArticleCategoriesRepository articleCategoriesRepository = new ArticleCategoriesRepository())
                {                   
                    //czy sa jakies artykuly podpiete do kategorii
                    using (ArticlesRepository articlesRepository = new ArticlesRepository())
                    {
                        listArticles = articlesRepository.GetArticlesByArticleCategoriesID(_articleCategory.ArticleCategoryID);
                    }
                    if (listArticles.Count == 0)
                    {
                        //czy ma podkategorie, zabronione usuwanie kategorii z podkategoriami
                        listArticleCategoriesTemp = articleCategoriesRepository.GetArticleCategoriesByIDIDCategoryIsNull(_articleCategory.ArticleCategoryID);
                        if (listArticleCategoriesTemp.Count == 0)
                        {                            
                            //usuwanie kategorii                        
                            using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                            {
                                articleCategoryOperRepository.DeleteArticleCategory(_articleCategory);
                            }                            

                            //modyfikacja seqAll dla wszystkich
                            listArticleCategoriesTemp = articleCategoriesRepository.GetAll();
                            using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                            {
                                for (int i = _articleCategory.SeqAllCategory + 1; i <= listArticleCategoriesTemp.Count() + 1; i++)
                                {
                                    articleCategoryTemp = articleCategoriesRepository.GetArticleCategoryBySeqAll(i);
                                    articleCategoryTemp.SeqAllCategory = i - 1;
                                    articleCategoryOperRepository.UpdateArticleCategory(articleCategoryTemp);
                                }
                            }
                            
                            //modyfikacja seq dla jednej rodziny
                            listArticleCategoriesTemp = articleCategoriesRepository.GetArticleCategoriesByIDIDCategoryIsNull(_articleCategory.ArticleCategoryIDID);
                            using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                            {
                                int i = 1;
                                foreach (ArticleCategoryT item in listArticleCategoriesTemp)
                                {
                                    item.SeqCategory = i;
                                    articleCategoryOperRepository.UpdateArticleCategory(item);
                                    i++;
                                }
                            }                            
                            
                            //nie zawiera podrzednych kategorii
                            InformationSuccess = InformationUserDictionary.Instance.GetInformationSuccessText(1);
                        }
                        else
                        {
                            //zawiera podrzedne kategorie- komunikat                   
                            InformationNotice = InformationUserDictionary.Instance.GetInformationNoticeText(1);
                        }
                    }
                    else
                    {
                        //zawiera artykuly w wybranej aktegorii- komunikat                
                        InformationNotice = InformationUserDictionary.Instance.GetInformationNoticeText(2);
                    }
                }
            }
            catch (Exception ex)
            {
                InformationException = InformationUserDictionary.Instance.GetInformationExceptionText(8) + ex.Message;
            }

        }
    
    }
}
